package Main;

public class Board {

	/*
	 * M--> X not0.
	 * 
	 * v2--> 2XX.
	 * 
	 * V3--> 3XX.
	 * 
	 * H2--> 2XXX.
	 */
	int[][] b;
	int V2n;
	int V3n;
	int H2n;

	public Board(int n) {
		b = new int[n][n];
		V2n = 1;
		V3n = 1;
		H2n = 1;
		setBoardConfig3();
		//gen();
		// V2n--;
		// V3n--;
		// H2n--;
	}

	public void insertT(int c, int x, int y) {
		switch (c) {
		case 0:
			b[2][0] = 1;
			b[2][1] = 1;
			break;
		case 1:
			if (y + 1 < b.length && b[x][y] == 0 && b[x][y + 1] == 0 && x != 2) {
				b[x][y] = 2000 + H2n;
				b[x][y + 1] = 2000 + H2n++;
			}
			break;
		case 2:
			if (x + 2 < b.length && b[x][y] == 0 && b[x + 1][y] == 0
					&& b[x + 2][y] == 0) {
				b[x][y] = 300 + V3n;
				b[x + 1][y] = 300 + V3n;
				b[x + 2][y] = 300 + V3n++;
			}
			break;
		case 3:
			if (x + 1 < b.length && b[x][y] == 0 && b[x + 1][y] == 0) {
				b[x][y] = 200 + V2n;
				b[x + 1][y] = 200 + V2n++;
			}
			break;
		}
	}

	public void gen() {

		this.insertT(0, 0, 0);

		for (int i = 0; i < 25; i++) {
			int c = (int) (Math.random() * 3 + 1);
			int x = (int) (Math.random() * 6);
			int y = (int) (Math.random() * 6);
			this.insertT(c, x, y);
		}

	}

	public void display() {
		for (int k = 0; k < this.b.length; k++) {
			for (int j = 0; j < this.b[k].length; j++) {
				switch ((int) (this.b[k][j] / 100)) {

				case 0:
					if (this.b[k][j] != 0)
						System.out.print("M" + "\t");
					else
						System.out.print("0" + "\t");
					break;
				case 2:
					System.out.print("v" + this.b[k][j] % 100 + "\t");
					break;
				case 3:
					System.out.print("V" + this.b[k][j] % 100 + "\t");
					break;
				case 20:
					System.out.print("H" + this.b[k][j] % 100 + "\t");
					break;

				}

			}
			System.out.println();
		}
	}

	public void move(int tileID, char dir) {
		int x = 0;
		int y = 0;

		boolean find = true;
		for (int i = 0; i < b.length && find; i++) {
			for (int j = 0; j < b[i].length; j++) {
				if (b[i][j] == tileID) {
					x = i;
					y = j;
					find = false;
					break;
				}
			}
		}

		switch (dir) {
		case 'r':
			for (int i = y + 2; i < b.length; i++) {
				if (b[x][i] != 0) {
					b[x][y] = 0;
					b[x][y + 1] = 0;
					b[x][i - 1] = tileID;
					b[x][i - 2] = tileID;
					break;
				} else if (i == b.length - 1) {
					b[x][y] = 0;
					b[x][y + 1] = 0;
					b[x][i - 1] = tileID;
					b[x][i] = tileID;
				}
			}
			break;
		case 'l':
			for (int i = y - 1; i >= 0; i--) {
				if (b[x][i] != 0) {
					b[x][y] = 0;
					b[x][y + 1] = 0;
					b[x][i + 1] = tileID;
					b[x][i + 2] = tileID;
					break;
				} else if (i == 0) {
					b[x][y] = 0;
					b[x][y + 1] = 0;
					b[x][i] = tileID;
					b[x][i + 1] = tileID;
				}
			}
			break;
		case 'u':
			for (int i = x - 1; i >= 0; i--) {
				if (b[i][y] != 0) {
					b[x][y] = 0;
					b[x + 1][y] = 0;
					if (tileID / 100 == 3) {
						b[x + 2][y] = 0;
						b[i + 3][y] = tileID;
					}
					b[i + 1][y] = tileID;
					b[i + 2][y] = tileID;
					break;
				} else if (i == 0) {
					b[x][y] = 0;
					b[x + 1][y] = 0;
					if (tileID / 100 == 3) {
						b[x + 2][y] = 0;
						b[i + 2][y] = tileID;
					}
					b[i][y] = tileID;
					b[i + 1][y] = tileID;
				}

			}
			break;
		case 'd':
			for (int i = x + tileID / 100; i < b.length; i++) {
				if (b[i][y] != 0) {
					b[x][y] = 0;
					b[x + 1][y] = 0;
					if (tileID / 100 == 3) {
						b[x + 2][y] = 0;
						b[i - 3][y] = tileID;
					}
					b[i - 1][y] = tileID;
					b[i - 2][y] = tileID;
					break;
				} else if (i == b.length - 1) {
					b[x][y] = 0;
					b[x + 1][y] = 0;
					if (tileID / 100 == 3) {
						b[x + 2][y] = 0;
						b[i - 2][y] = tileID;
					}
					b[i][y] = tileID;
					b[i - 1][y] = tileID;
				}

			}
			break;
		}

	}

	public Board clone() {
		Board newBoard = new Board(this.b.length);
		for (int i = 0; i < b.length; i++) {
			for (int j = 0; j < b.length; j++) {
				newBoard.b[i][j] = b[i][j];
			}
		}
		newBoard.H2n = this.H2n;
		newBoard.V2n = this.V2n;
		newBoard.V3n = this.V3n;

		return newBoard;
	}

	public int[][] getB() {
		return b;
	}

	public void setB(int[][] b) {
		this.b = b;
	}

	public boolean[] possibleMoves() {

		boolean[] possMoves = new boolean[2 * (1 + H2n + V2n + V3n)];

		for (int i = 0; i < b.length; i++) {
			for (int j = 0; j < b.length; j++) {
				int r = b[i][j] % 100;
				switch (b[i][j] / 100) {
				case 0:
					if (this.b[i][j] != 0) {
						possMoves[0] = possMoves[0]
								|| (j != 0 && b[i][j - 1] == 0);
						possMoves[1] = possMoves[1]
								|| (j != b.length - 1 && b[i][j + 1] == 0);
					}
					break;

				case 2:
					possMoves[2 * (H2n + r)] = possMoves[2 * (H2n + r)]
							|| (i != 0 && b[i - 1][j] == 0);
					possMoves[2 * (H2n + r) + 1] = possMoves[2 * (H2n + r) + 1]
							|| (i != b.length - 1 && b[i + 1][j] == 0);
					break;
				case 3:
					possMoves[2 * (H2n + V2n + r)] = possMoves[2 * (H2n + V2n + r)]
							|| (i != 0 && b[i - 1][j] == 0);
					possMoves[2 * (H2n + V2n + r) + 1] = possMoves[2 * (H2n
							+ V2n + r) + 1]
							|| (i != b.length - 1 && b[i + 1][j] == 0);
					break;
				case 20:
					possMoves[2 * r] = possMoves[2 * r]
							|| (j != 0 && b[i][j - 1] == 0);
					possMoves[2 * r + 1] = possMoves[2 * r + 1]
							|| (j != b.length - 1 && b[i][j + 1] == 0);
					break;
				}

			}
		}

		return possMoves;
	}

	public int getV2n() {
		return V2n;
	}

	public void setV2n(int v2n) {
		V2n = v2n;
	}

	public int getV3n() {
		return V3n;
	}

	public void setV3n(int v3n) {
		V3n = v3n;
	}

	public int getH2n() {
		return H2n;
	}

	public void setH2n(int h2n) {
		H2n = h2n;
	}

	// solvable
	public void setBoardConfig1() {
		if (b.length != 6 || b[0].length != 6) {
			return;
		}

		b = new int[][] { { 0, 2002, 2002, 2004, 2004, 0 },
				{ 0, 0, 2001, 2001, 0, 0 }, { 1, 1, 301, 0, 0, 0 },
				{ 202, 302, 301, 204, 201, 203 },
				{ 202, 302, 301, 204, 201, 203 }, { 0, 302, 2003, 2003, 0, 0 } };
		H2n = 4;
		V2n = 4;
		V3n = 2;

	}

	// solvable with nothing in front of the mouse
	public void setBoardConfig2() {
		if (b.length != 6 || b[0].length != 6) {
			return;
		}
		b = new int[][] { { 0, 2002, 2002, 2004, 2004, 0 },
				{ 0, 0, 2001, 2001, 0, 0 }, { 1, 1, 0, 0, 0, 0 },
				{ 202, 302, 0, 204, 201, 203 }, { 202, 302, 0, 204, 201, 203 },
				{ 0, 302, 2003, 2003, 0, 0 } };
		H2n = 4;
		V2n = 4;
		V3n = 1;

	}

	// not solvable
	public void setBoardConfig3() {
		if (b.length != 6 || b[0].length != 6) {
			return;
		}
		b = new int[][] { { 0, 2002, 2002, 2004, 2004, 0 },
				{ 0, 0, 2001, 2001, 0, 0 }, { 1, 1, 301, 2005, 2005, 0 },
				{ 202, 302, 301, 204, 201, 203 },
				{ 202, 302, 301, 204, 201, 203 }, { 0, 302, 2003, 2003, 0, 0 } };
		H2n = 5;
		V2n = 4;
		V3n = 2;

	}

}